#ifndef _CHANNELS_H_
#define _CHANNELS_H_


#include "Common.h"
#include "String.h"
#include "SharedPtr.h"
#include "Resource.h"
#include "Character.h"
#include "Effects.h"
#include "XMLData.h"


class ChannelPtr;
class CharPtr;
class ItemPtr;
class BSSocketPtr;
class BattleMapPtr;
class WorldPacket;

enum ChannelContainerTypes
{
	ChannelContainerTypeNone 		= 0,
	ChannelContainerTypeCharacter 		= 1,
	ChannelContainerTypeChannel		= 2,
	ChannelContainerTypeCity		= 3,
	ChannelContainerTypeCountry		= 4,
	ChannelContainerTypeOther		= 5
};



//战场公共属性
typedef struct channel_common_property
{
	ResourceProxy		uplink;
	Vector3			position;

	void initialize(void)
	{
	
		position = Vector3::ZERO;	
		uplink.setNull();
	}

	channel_common_property()
	{
		initialize();
	}

}channel_common_property_t;



class Channel :public Resource
{
	friend	class ProtocolsManager;
public:
	Channel(ResourceManager* creator, const String& name, ResourceHandle handle,
            const String& group, bool isManual = false, ManualResourceLoader* loader = 0);
	~Channel(void);
	
	enum ChannelStatus
	{
		ChannelStatusNone = 		0,
		ChannelStatusReq  = 		1, //战场建立请求
		ChannelStatusProcess = 		2, //战场建立完成，开始自动处理
		ChannelStatusDone =		3, //战场处理结束
		ChannelStatusWorldProcess = 	4, //世界服务器处理开始
		ChannelStatusWorldDone = 	5, //世界服务器处理完毕
		ChannelStatusError = 		6, //战场处理错误
		ChannelStatusTimeOut = 		7, //战场处理超时
		ChannelStatusWorldError =	8, //世界服务器处理错误
		ChannelStatusWorldWait  =	9, //世界等待处理
		ChannelStatusDeleted	=	255  //数据删除 
	};

	enum ChannelWinnerStatus
	{
		ChannelWinnerStatusNone		=0,	//无效状态
		ChannelWinnerStatusAttacker	=1,	//攻击方胜利
		ChannelWinnerStatusDefence	=2,	//防御方胜利
		ChannelWinnerStatusTied		=3	//和局
	};

protected:
       	void prepareImpl(void);
        /** Destroys data cached by prepareImpl.
         */
        void unprepareImpl(void);
        /// @copydoc Resource::loadImpl
        bool loadImpl(void);
        /// @copydoc Resource::postLoadImpl
        void postLoadImpl(void);
        /// @copydoc Resource::unloadImpl
        void unloadImpl(void);

	void preUnloadImpl(void);

        /// @copydoc Resource::calculateSize
        size_t calculateSize(void) const;
protected:
	std::list<ResourceProxy>	m_chars;	//战场中的武将数
	std::list<ResourceProxy>	m_items;	//战场中的城防物品
	std::list<ResourceProxy>	m_clients;	//战场链接的客户端数
	std::list<ResourceProxy>	m_effects;	//战场作用的效果
	

	uint32		m_serial;
	uint32		m_group_id;
	bool		m_idle;			//标识频道在自动线程处理中

	bool		m_wantRemove;		//标识频道将被删除 在主线程中操作
	bool		m_removed;		//标识频道进入删除线程

	uint32		m_timelast;		//记录频道下一次自动检查的时间 ms

public:
	const uint32  & getSerial() 	{	return m_serial;	}
	const uint32  & getGroup_id()	{	return m_group_id;	}


	//添加将领到战场中
	bool    addChar(const uint32 & serial);
        bool    addChar(ResourceProxy & ch);
        bool    removeChar(const uint32 & serial);
        bool    removeChar(ResourceProxy  & ch);
	bool	deleteChar(const uint32 & serial);
	bool	deleteChar(ResourceProxy & ch);
        bool    destroyChar(const uint32 & serial);
        bool    destroyChar(ResourceProxy & ch);
        void    removeAllChars(void);
	void	deleteAllChars(void);
        void    destroyAllChars(void);
	

	//将物品添加到战场中
	bool	addItem(const uint32 & serial);
	bool  	addItem(ResourceProxy & item);
	bool	removeItem(const uint32 & serial);
	bool	removeItem(ResourceProxy & item);
	bool	deleteItem(const uint32 & serial);
	bool	deleteItem(ResourceProxy & item);
	bool	destroyItem(const uint32 & serial);
	bool	destroyItem(ResourceProxy & item);
	void 	removeAllItems(void);
	void	deleteAllItems(void);
	void	destroyAllItems(void);

	//添加Socket到频道中
	bool	addSocket( BSSocketPtr & sock);
	bool	removeSocket(uint32 serial);
	bool	removeSocket(BSSocketPtr & sock);
	void	removeAllSockets(void);
	void 	destroyAllSockets(void);
	size_t	getSocketCount(void)	{	return m_clients.size();	}
	
	//添加效果到
	bool	addEffect(const uint32 & serial);
	bool	addEffect(ResourceProxy & effect);
	bool	removeEffect(const uint32 & serial);
	bool	removeEffect(ResourceProxy & effect);
	bool    deleteEffect(const uint32 & serial);
        bool    deleteEffect(ResourceProxy & effect);
	bool    destroyEffect(const uint32 & serial);
        bool    destroyEffect(ResourceProxy & effect);
	void	removeAllEffects(void);
	void	deleteAllEffects(void);
	void	destroyAllEffects(void); 

	//save channel to database	
	bool	SaveDB(void);
	bool	LoadDB(void);
	bool    FetchDB(Field * fields);


	void	Delete(void);
	void	Destroy(void);

	//用户数据
        XMLDataSet      user_data;

	//设置频道处理标识为忙，避免重复队列处理
	void	setBusy(void)		{	m_idle = false;	}
	void	setIdle(void)		{	m_idle = true;	}
	bool	isBusy(void)		{	return (m_idle == false);	}

	bool	isWantRemove(void)	{	return m_wantRemove;	}
	void   setWantRemove(void)	{	m_wantRemove = true;	}
	
	bool	isRemoved(void)		{	return m_removed;	}
	void 	setRemoved(void)	{	m_removed = true;	}
	
	//channel auto check
	bool	run(const uint32 & p_time);
	//检查频道是否进行自动更新
	bool	checkUpdate(const uint32 & timenow)	{  return (m_idle && timenow > m_timelast) ? true:false;}
	void 	updateTimeLast(const uint32 & timelast)	{	m_timelast = timelast;	}
	//获取军队列表副本，如果参数为0 返回军队列表本身
	std::list<ItemPtr> * getItemsList(std::list<ItemPtr> * list = 0);	
	std::list<CharPtr> * getCharsList(std::list<CharPtr> * list = 0);	
	std::list<BSSocketPtr> * getSocketsList(std::list<BSSocketPtr> * list = 0);	
	//得到包括特效的列表复制
	std::list<EffectPtr> * getEffectsList(std::list<EffectPtr> * list);
	
	void	BroadcastPacket(WorldPacket * packet);

	//初始化清除频道数据
	void    initialize(void);

	channel_common_property_t	common;
};

    /** Specialisation of SharedPtr to allow SharedPtr to be assigned to ChannelPtr 
    @note Has to be a subclass since we need operator=.
    We could templatise this instead of repeating per Resource subclass, 
    except to do so requires a form VC6 does not support i.e.
    ResourceSubclassPtr<T> : public SharedPtr<T>
    */
    class SERVER_DECL  ChannelPtr : public SharedPtr<Channel>
    {
    public:
        ChannelPtr() : SharedPtr<Channel>() {}
        explicit ChannelPtr(Channel* rep) : SharedPtr<Channel>(rep) {}
        ChannelPtr(const ChannelPtr& r) : SharedPtr<Channel>(r) {}
        ChannelPtr(const ResourcePtr& r);
        /// Operator used to convert a ResourcePtr to a MeshPtr
        ChannelPtr& operator=(const ResourcePtr& r);
    protected:
        /// Override destroy since we need to delete Mesh after fully defined
        void destroy(void);
    };
	

#endif
